﻿#include <QCoreApplication>
#include <QDBusInterface>
#include <QDBusMetaType>
#include <QDBusReply>
#include <QDBusConnection>
#include <QDBusVirtualObject>
#include <QDBusMessage>
#include <QDebug>
#include "dbus-monitor.h"

#define SYSTEMD_SERVICE         "org.freedesktop.login1"
#define SYSTEMD_PATH            "/org/freedesktop/login1"
#define SYSTEMD_INTERFACE       "org.freedesktop.login1.Manager"

// dbus-send --print-reply --system --dest=org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager.ListSessions
struct SessionInfo
{
    QString sessionId;
    uint userId;
    QString userName;
    QString seatId;
    QDBusObjectPath sessionPath;
};
typedef QList<SessionInfo> SessionInfoList;
Q_DECLARE_METATYPE(SessionInfoList);
Q_DECLARE_METATYPE(SessionInfo);


inline QDBusArgument &operator<<(QDBusArgument &argument, const SessionInfo& sessionInfo)
{
    argument.beginStructure();
    argument << sessionInfo.sessionId;
    argument << sessionInfo.userId;
    argument << sessionInfo.userName;
    argument << sessionInfo.seatId;
    argument << sessionInfo.sessionPath;
    argument.endStructure();

    return argument;
}

inline const QDBusArgument &operator>>(const QDBusArgument &argument, SessionInfo &sessionInfo)
{
    argument.beginStructure();
    argument >> sessionInfo.sessionId;
    argument >> sessionInfo.userId;
    argument >> sessionInfo.userName;
    argument >> sessionInfo.seatId;
    argument >> sessionInfo.sessionPath;
    argument.endStructure();

    return argument;
}

int main(int argc, char *argv[])
{
    qRegisterMetaType<SessionInfo>("SessionInfo");
    qRegisterMetaType<SessionInfoList>("SessionInfoList");
    qDBusRegisterMetaType<SessionInfo>();
    qDBusRegisterMetaType<SessionInfoList>();
    QCoreApplication a(argc, argv);

    QDBusInterface interface( SYSTEMD_SERVICE,
                                  SYSTEMD_PATH,
                                  SYSTEMD_INTERFACE,
                                  QDBusConnection::systemBus() );
    QDBusReply<SessionInfoList> reply = interface.call(QStringLiteral("ListSessions"));
    QDBusMessage rmsg = interface.call(QStringLiteral("ListSessions"));
    qDebug() << rmsg.arguments().at(0);
    QDBusArgument const &arg = rmsg.arguments().at(0).value<QDBusArgument>();
    qDebug() << arg.currentType();
    arg.beginArray();
    while(!arg.atEnd()) {
        SessionInfo si;
        arg >> si;
        qDebug() << "uid:" << si.userId;

    }
    arg.endArray();
    for(int i = 0; i < reply.value().count(); i++){
        qDebug() << "User(" << i <<  "):";
        qCritical() << "sid:" << reply.value().at(i).sessionId;
        qCritical() << "uid:" << reply.value().at(i).userId;
        qCritical() << "uname:" << reply.value().at(i).userName;
    }

    DBusMonitor dbm;
    QDBusConnection::sessionBus().registerVirtualObject("/org/freedesktop/Notifications", &dbm);

    QString matchString = "interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'";
    QDBusInterface busInterface("org.freedesktop.DBus", "/org/freedesktop/DBus",
                                "org.freedesktop.DBus");
    busInterface.call("AddMatch", matchString);



    return a.exec();
    return 0;
}
